package practise.mulitThreads.ConcurrentInPractice.secondTime;

import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Created by Richard on 7/28/2014.
 */
public class CustomerizedSemaphore {
    private Lock lock = new ReentrantLock();
    private Condition condition = lock.newCondition();
    private AtomicInteger integer ;
    public CustomerizedSemaphore(int size){
        integer = new AtomicInteger(size);
    }
    public void acquire(){
        try{
            lock.lock();
            if(integer.getAndDecrement()<0){
                waitForSemaphore();
            }

        }
        finally {
            lock.unlock();
        }
    }

    public void release(){
        try{
            lock.lock();
            integer.incrementAndGet();
            notifyForSemaphoreWait();
        }
        finally {
            lock.unlock();
        }
    }


    private void waitForSemaphore(){
        try{
            lock.lock();
            condition.await();

        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        finally {
            lock.unlock();
        }
    }
    private void notifyForSemaphoreWait(){
        try{
            lock.lock();
            condition.signal();

        }
        finally {
            lock.unlock();
        }
    }
}
